/**
 * 
 */
package com.honghao.student.md5;

import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;

import org.apache.commons.codec.binary.Base64;

/**
 * @author honghao.li
 * 
 */
public class StringEncrypter implements IEncrypt {

    /**
     * 密匙
     */
    private KeySpec keySpec;

    /**
     * A factory for secret keys
     */
    private SecretKeyFactory keyFactory;

    /**
     * 加密和解密
     */
    private Cipher cipher;

    private String transformation;// kept for reinitialization of cipher

    /**
     * 构造新的Encrypter基于指定的加密方案 用户加密密钥将被设置为默认值
     * 
     * @param encryptionScheme
     * @throws Exception
     */
    public StringEncrypter(String encryptionScheme) {
        this(encryptionScheme, IEncrypt.DEFAULT_ENCRYPTION_KEY);
    }
    /**
     * 
     * 用户自定义密匙构建
     * @param encryptionScheme
     * @param encryptionKey
     * @throws Exception
     */
    public StringEncrypter(String encryptionScheme, String encryptionKey) {
        if (encryptionKey == null)
            throw new IllegalArgumentException("encryption key is null");
        try {
            byte[] keyAsBytes = encryptionKey.getBytes(IEncrypt.UNICODE_FORMAT);

            if (encryptionScheme.equals(IEncrypt.DESEDE_ENCRYPTION_SCHEME)) {
                keySpec = new DESedeKeySpec(keyAsBytes);
            } else if (encryptionScheme.equals(IEncrypt.DES_ENCRYPTION_SCHEME)) {
                keySpec = new DESKeySpec(keyAsBytes);
            } else {
                throw new IllegalArgumentException(
                        "Encryption scheme not supported: " + encryptionScheme);
            }

            keyFactory = SecretKeyFactory.getInstance(encryptionScheme);
            cipher = Cipher.getInstance(encryptionScheme);
            this.transformation = encryptionScheme;

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /*
     * (non-Javadoc)
     * 加密函数，将原文加密成密文
     * @see com.honghao.student.md5.IEncrypt#encrypt(java.lang.String)
     */
    @Override
    public String encrypt(String unencryptedString) {
        String encryptedString = "";

        if (unencryptedString != null && unencryptedString.trim().length() > 0) {

            try {
                // 生成Cipher对象
                if (cipher == null)
                    cipher = Cipher.getInstance(transformation);
                SecretKey key = keyFactory.generateSecret(keySpec);
                //用密钥加密明文,生成密文
                cipher.init(Cipher.ENCRYPT_MODE, key);//操作模式为加密(Cipher.ENCRYPT_MODE)
                byte[] cleartext = unencryptedString
                        .getBytes(IEncrypt.UNICODE_FORMAT);
                //得到加密后的字节数组
                byte[] ciphertext = cipher.doFinal(cleartext);
                System.out.println("加密后的字节数组"+ciphertext);
                Base64 base64encoder = new Base64();
                encryptedString = new String(base64encoder.encode(ciphertext));
            } catch (Exception e) {
                // sometimes the cipher can really break internally, rendering
                // it useless. depends on the implementation
                cipher = null;
                e.printStackTrace();
            }
        }
        return encryptedString;
    }
    
    
    /**
     * 解密
     */
    @Override
    public String unencrypt(String encryptedString){
        byte[] text = new Base64().decode(encryptedString);
        System.out.println("Base64解密后的字节数组"+text);
        byte[] sourcetext = null;
        try {
            SecretKey key = keyFactory.generateSecret(keySpec);
            cipher.init(Cipher.DECRYPT_MODE, key);
            sourcetext = cipher.doFinal(text);
            System.out.println("cipher解密后字节数组"+sourcetext);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new String(sourcetext);
    }
}
